import 'package:flutter/material.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';

import 'index.dart';

// 在类外部维护眨眼检测状态
final Map<int, _BlinkState> _blinkStates = {};

class _BlinkState {
  bool lastEyesOpen = true;
  int? blinkStartTime;
  bool hasBlinked = false;
}

class FaceIdentifier {
  static Future<DetectedFace?> scanImage({
    required InputImage cameraImage,
    required FaceDetectorMode performanceMode,
  }) async {
    DetectedFace? result;
    final face = await _detectFace(
      performanceMode: performanceMode,
      visionImage: cameraImage,
    );
    if (face != null) {
      result = face;
    }

    return result;
  }

  static const int eyesOpenMs = 300;
  static const int headEulerAngleXMax = 20;
  static const int headEulerAngleYMax = 15;
  static const int boundingBoxOffset = 30;
  static Future<DetectedFace?> _detectFace({
    required InputImage? visionImage,
    required FaceDetectorMode performanceMode,
  }) async {
    if (visionImage == null) return null;
    final options = FaceDetectorOptions(
      enableContours: false,
      enableClassification: true, //分类功能
      enableLandmarks: false,
      enableTracking: true, //面部跟踪
      performanceMode: performanceMode,
    );
    final faceDetector = FaceDetector(options: options);
    try {
      final List<Face> faces = await faceDetector.processImage(visionImage);
      final faceDetect = _extractFace(
        faces,
        metadata: visionImage.metadata,
      );
      return faceDetect;
    } catch (error) {
      debugPrint('FaceIdentifier.detectFace.ERROR--->${error.toString()}');
      return null;
    }
  }

  static _extractFace(List<Face> faces, {InputImageMetadata? metadata}) {
    //List<Rect> rect = [];
    bool wellPositioned = faces.isNotEmpty;
    Face? detectedFace;
    bool isRealPerson = false;

    for (Face face in faces) {
      final trackingId = face.trackingId;

      /// 初始化眨眼状态
      if (trackingId != null) {
        if (_blinkStates.entries.where((f) => f.key != trackingId).isNotEmpty) {
          _blinkStates.removeWhere((key, value) => key != trackingId);
        }
        if (!_blinkStates.containsKey(trackingId)) {
          _blinkStates[trackingId] = _BlinkState();
        }
      }
      // 眨眼检测逻辑
      if (trackingId != null &&
          face.leftEyeOpenProbability != null &&
          face.rightEyeOpenProbability != null) {
        final currentTime = DateTime.now().millisecondsSinceEpoch;
        final blinkState = _blinkStates[trackingId]!;

        debugPrint('hasBlinked--->${blinkState.hasBlinked}');
        if (!blinkState.hasBlinked) {
          final bothEyesOpen = face.leftEyeOpenProbability! > 0.6 &&
              face.rightEyeOpenProbability! > 0.6;
          final bothEyesClosed = face.leftEyeOpenProbability! < 0.2 &&
              face.rightEyeOpenProbability! < 0.2;

          // 状态转换检测
          if (bothEyesClosed && blinkState.lastEyesOpen) {
            // 检测到闭眼开始
            blinkState.blinkStartTime = currentTime;
            blinkState.lastEyesOpen = false;
          } else if (bothEyesOpen && !blinkState.lastEyesOpen) {
            // 检测到睁眼完成眨眼
            if (blinkState.blinkStartTime != null &&
                (currentTime - blinkState.blinkStartTime!) < eyesOpenMs) {
              blinkState.hasBlinked = true;
            }
            blinkState.lastEyesOpen = true;
          }
        }
        isRealPerson = blinkState.hasBlinked;
      }
      detectedFace = face;
      if (detectedFace.headEulerAngleY != null &&
          detectedFace.headEulerAngleX != null) {
        if (detectedFace.headEulerAngleY!.abs() > headEulerAngleXMax ||
            detectedFace.headEulerAngleX!.abs() > headEulerAngleYMax) {
          wellPositioned = false;
        }
        debugPrint(
            'FaceIdentifier.face:Tracking ID--->${face.trackingId},headEulerAngleY:${face.headEulerAngleY?.abs()},headEulerAngleX--->${face.headEulerAngleX!.abs()},leftEyeOpenProbability:${face.leftEyeOpenProbability},leftEyeOpenProbability:${face.rightEyeOpenProbability},isRealPerson:$isRealPerson');
      }
      if (wellPositioned && metadata != null) {
        // 定义安全区域边界
        final minEdge = boundingBoxOffset.toDouble();
        final width = [
          InputImageRotation.rotation0deg,
          InputImageRotation.rotation180deg
        ].contains(metadata.rotation)
            ? metadata.size.width
            : metadata.size.height;
        final height = [
          InputImageRotation.rotation0deg,
          InputImageRotation.rotation180deg
        ].contains(metadata.rotation)
            ? metadata.size.height
            : metadata.size.width;

        final maxWidth = width - boundingBoxOffset;
        final maxHeight = height - boundingBoxOffset;

        // 解构人脸框数据
        final rect = detectedFace.boundingBox;
        final left = rect.left;
        final top = rect.top;
        final right = rect.right;
        final bottom = rect.bottom;

        /// 检查是否超出安全区域
        final isFaceInSafeArea = left >= minEdge &&
            top >= minEdge &&
            right <= maxWidth &&
            bottom <= maxHeight;

        wellPositioned = isFaceInSafeArea;
        debugPrint(
            'FaceIdentifier.face.Edge--->ImageWidth:$width,imageHeight:$height},left:$left>=minEdge:$minEdge==>${left >= minEdge},top:$top>=left:$minEdge==>${top >= minEdge},right:$right<=maxWidth:$maxWidth==>${right <= maxWidth},bottom:$bottom<=maxHeight:$maxHeight==>${bottom <= maxHeight}');
      }
      debugPrint(
          'FaceIdentifier.face:Tracking ID--->${face.trackingId},detectedFace.boundingBox:(left:${detectedFace.boundingBox.left},right:${detectedFace.boundingBox.right},top:${detectedFace.boundingBox.top},bottom:${detectedFace.boundingBox.bottom}),headEulerAngleY:${face.headEulerAngleY?.abs()},headEulerAngleX--->${face.headEulerAngleX!.abs()},leftEyeOpenProbability:${face.leftEyeOpenProbability},leftEyeOpenProbability:${face.rightEyeOpenProbability},isRealPerson:$isRealPerson');
    }
    return DetectedFace(
      wellPositioned: wellPositioned,
      face: detectedFace,
      size: metadata?.size,
      isRealPerson: isRealPerson,
    );
  }
}
